DSFX.Effect = function( el, opts )
{
	this.element = DSFX.util.$(el);
	this.classes = opts.to.split(' ') || "";
	this.overrides = opts.overrides;
	this.duration = opts.duration;
	this.easement = opts.easement;
	this.tween = new DSFX.Tween( this.duration, this.easement );
	return this;
};

DSFX.Effect.prototype = 
{	 
	go: function()
	{
		var cache = { style: {} }, el = this.element;

		for ( var i=0, len=el.style.length; i<len; i++ )
		{
			cache.style[el.style[i]] = el.style[el.style[i]];
		}

		for ( var style in this.overrides )
		{
			el.style[style] = this.overrides[style] + "!important";
			cache.style[style] = this.overrides[style];
		}

		var origin = DSFX.util.animatableStyles( DSFX.util.currentStyles( el ) ),
			conclusion = DSFX.util.futureStyles( el, this.classes );
		
		for ( style in origin )
		{
			if ( conclusion[ style ] != origin[ style ] )
			{
				new DSFX.Tweenie( el, style, origin[ style ], conclusion[ style ], this.tween );
			}
		}
		DSFX.util.on( this.tween, 'end', DSFX.util.fix( this, function()
		{
			el.className = this.classes.join(' ');
			for ( var style in origin )
			{
				el.style[style] = null;
			}
			for ( style in cache.style )
			{
				el.style[style] = cache.style[style];
			}
			for ( style in this.overrides )
			{
				el.style[style] = this.overrides[style];
			}
		}));
		
		this.tween.go();
	},
	
	chain: function( chainer )
	{
		DSFX.util.on( this.tween, 'end', function(){setTimeout(DSFX.util.fix( chainer, chainer.go ),10)});
	}	
};